package com.ailot.cloud.base.security.utils;


import com.ailot.cloud.base.security.model.JwtUser;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
import org.springframework.security.oauth2.jwt.JwtEncoderParameters;

import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.stream.Collectors;

import static com.ailot.cloud.base.common.constants.SecurityConstant.*;


@Slf4j
@UtilityClass
public class JWTUtil {


    private final static String ISSUER = "AILOT";


    private static Long expire = 24L;

    @Value("${jwt.expire}")
    public static void setExpire(Long expire) {
        JWTUtil.expire = expire;
    }

    /**
     * 通过认证信息返回 jwt数据
     */
    public static JwtEncoderParameters authenticationToJwtParameters(JwtUser jwtUser) {

        Instant now = Instant.now();

        List<GrantedAuthority> list = jwtUser.getAuthorities().stream().collect(Collectors.toList());
        List<String> stringList = list.stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());

        // 构造一致的 jwt
        JwtClaimsSet claims = JwtClaimsSet.builder()
                .issuer(ISSUER)
                .issuedAt(now)
                .expiresAt(now.plus(Duration.ofHours(expire)))
                .subject(jwtUser.getUsername())
                // 认证用户信息
                .claim(ID, jwtUser.getId())
                .claim(ORGID, jwtUser.getOrgId())
                .claim(USERNAME, jwtUser.getUsername())
                .claim(AUTHORITIES, stringList)
                .build();

        return JwtEncoderParameters.from(claims);
    }

    public static JwtUser principalFrom(Jwt jwt) {
        //从jwt中恢复用户信息和权限
        String id = jwt.getClaim(ID);
        String orgId = jwt.getClaim(ORGID);
        String username = jwt.getClaim(USERNAME);
        List<String> authorities = jwt.getClaim(AUTHORITIES);
        JwtUser jwtUser = new JwtUser(id, orgId, username, "", AuthorityUtils.createAuthorityList(authorities.stream().toArray(String[]::new)));
        return jwtUser;

    }
}
